/***********************************************************************************************************************
*                                                                                                                      *
* SPLASH build system v0.1                                                                                             *
*                                                                                                                      *
* Copyright (c) 2013 Andrew D. Zonenberg                                                                               *
* All rights reserved.                                                                                                 *
*                                                                                                                      *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the     *
* following conditions are met:                                                                                        *
*                                                                                                                      *
*    * Redistributions of source code must retain the above copyright notice, this list of conditions, and the         *
*      following disclaimer.                                                                                           *
*                                                                                                                      *
*    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the       *
*      following disclaimer in the documentation and/or other materials provided with the distribution.                *
*                                                                                                                      *
*    * Neither the name of the author nor the names of any contributors may be used to endorse or promote products     *
*      derived from this software without specific prior written permission.                                           *
*                                                                                                                      *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR       *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE       *
* POSSIBILITY OF SUCH DAMAGE.                                                                                          *
*                                                                                                                      *
***********************************************************************************************************************/

#ifndef CppLinkFlags_h
#define CppLinkFlags_h

class BuildGraph;
class BuildGraphNode;

/**
	@brief Specifies a custom linker script to use
 */
class CppLinkerScriptFlag : public CppLinkFlag
{
public:
	CppLinkerScriptFlag(std::string name);
	virtual ~CppLinkerScriptFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
	
	std::string GetName() const
	{ return m_name; }
	
protected:
	std::string m_name;
};

/**
	@brief Specifies that the generated binary will include debug info
 */
class CppLinkDebugInfoFlag : public CppLinkFlag
{
public:
	CppLinkDebugInfoFlag();
	virtual ~CppLinkDebugInfoFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
};

/**
	@brief Specifies that the generated binary will run on bare metal with no OS, and no system libraries can be used
 */
class CppBareMetalFlag : public CppLinkFlag
{
public:
	CppBareMetalFlag();
	virtual ~CppBareMetalFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
};

/**
	@brief Specifies that code which is never called should be removed from the binary
 */
class CppDeadStripFlag : public CppLinkFlag
{
public:
	CppDeadStripFlag();
	virtual ~CppDeadStripFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
};

/**
	@brief Specifies the name of a library to be linked with the object files.
 */
class CppLinkLibraryByNameFlag : public CppLinkFlag
{
public:
	CppLinkLibraryByNameFlag(std::string name);
	virtual ~CppLinkLibraryByNameFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
	
protected:
	std::string m_name;
};

/**
	@brief Specifies the full path, including extension, of a library to be linked with the object files.
 */
class CppLinkLibraryByPathFlag : public CppLinkFlag
{
public:
	CppLinkLibraryByPathFlag(std::string path);
	virtual ~CppLinkLibraryByPathFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
	
protected:
	std::string m_path;
};

/**
	@brief Specifies a library to link to which is built by this graph
 */
class CppLinkLibraryByTargetNameFlag : public CppLinkFlag
{
public:
	CppLinkLibraryByTargetNameFlag(std::string name, BuildGraph* graph);
	virtual ~CppLinkLibraryByTargetNameFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
	
	BuildGraphNode* GetNode(const CppToolchain* toolchain);
	
	std::string GetName()
	{ return m_name; }
	
protected:
	std::string m_name;
	BuildGraph* m_graph;
};

/**
	@brief Adds link settings necessary for profiling / code coverage
 */
class CppLinkProfilingFlag : public CppLinkFlag
{
public:
	CppLinkProfilingFlag();
	virtual ~CppLinkProfilingFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
};

/**
	@brief Adds link settings necessary for OpenMP
 */
class CppLinkOpenMPFlag : public CppLinkFlag
{
public:
	CppLinkOpenMPFlag();
	virtual ~CppLinkOpenMPFlag();
	virtual CppLinkFlag* Clone() const;
	virtual std::string toString(const CppToolchain* toolchain);
};

#endif
